package com.learnyou.server.xingzuo.biz.helper;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.learnyou.server.xingzuo.common.helper.BinaryDigitHelper;
import com.learnyou.server.xingzuo.dto.paramDTO.WeekTimeDTO;

import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author heweifeng
 * @Description:
 * @date 2022/11/15 15:22
 */
public class CourseScheduleHelper {

    /**
     * 生成本月在指定星期范围内的日期
     * @param scheduleWeeks
     * @param start
     * @param end
     * @return
     */
    public static List<String> generateDaysOfSchedule(Integer scheduleWeeks, Date start, Date end, Integer totalSchedule){
        if (scheduleWeeks == null){
            return Collections.emptyList();
        }
        List<Integer> weeks = BinaryDigitHelper.weekNumTo(scheduleWeeks);
        List<String> days = new ArrayList<>();
        long maxDay = 20;

        if (totalSchedule!=null&&totalSchedule>0){
            maxDay = totalSchedule;
        }

        if(end!= null){
            maxDay = DateUtil.between(start, end, DateUnit.DAY);
            maxDay = maxDay==0?1:maxDay;
        }
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            DateTime day = DateUtil.offsetDay(start, i);
            if (days.size() > maxDay){
                break;
            }
            if (end!=null){
                if (DateUtil.compare(day, end) >0){
                    break;
                }
            }
            int week = DateUtil.dayOfWeekEnum(day).getIso8601Value();
            if (weeks.contains(week)){
                days.add(DateUtil.formatDate(day));
            }
        }

        return days.stream().limit(maxDay).collect(Collectors.toList());
    }

    /**
     * 每周哪几天上课时间安排
     * times填入周一到周日每天的上课时间，如果不上课，哪天的时间为空
     * times长度固定为7， 至少需要存在一天上课
     * times内容示例 ["10:00-11:00", "", "", "", "", "", ""]
     *
     * 解析times成WeekTimeDTO，格式化数据成标准格式，去除空数据
     * @param times
     * @return
     */
    public static List<WeekTimeDTO> parseCourseScheduleTimes(List<String> times){
        List<WeekTimeDTO> list = new ArrayList<>();
        for (int i = 0; i < times.size(); i++) {
            String timeStr = times.get(i);
            List<String> splitList = StrUtil.splitTrim(timeStr, '-');

            if(splitList.size()==2){
                list.add(new WeekTimeDTO(i+1, splitList.get(0), splitList.get(1)));
            }
        }

        return list;
    }

    /**
     * set scheduleTime 相关字段
     * @param times
     * @param bean
     */
    public static void setScheduleTimes(List<WeekTimeDTO> times, Object bean){
        if (CollUtil.isEmpty(times)){
            return;
        }
        times.forEach(time -> {
            BeanUtil.setProperty(bean, "startTime"+time.getWeek(), time.getStartTime());
            BeanUtil.setProperty(bean, "endTime"+time.getWeek(), time.getEndTime());
        });
    }

    /**
     * 转换bean中相关14个字段成一周时间列表
     * @param bean
     * @return
     */
    public static List<String> getScheduleTimes(Object bean){

        return IntStream.range(0,7)
                .mapToObj(t->new WeekTimeDTO(t+1, BeanUtil.getProperty(bean, "startTime"+(t+1)),BeanUtil.getProperty(bean, "endTime"+(t+1)) ))
                .map(t->{
                    if (StrUtil.isNotEmpty(t.getStartTime())){
                        return t.getStartTime()+'-'+t.getEndTime();
                    }else {
                        return "";
                    }
                })
                .collect(Collectors.toList());
    }

    /**
     * 获得某一天的开始结束时间
     * @param date
     * @param bean
     * @return
     */
    public static WeekTimeDTO getTimeOfDay(Date date, Object bean) {

        List<WeekTimeDTO> weekTimeDTOS = IntStream.range(0,7)
                .mapToObj(t->new WeekTimeDTO(t+1, BeanUtil.getProperty(bean, "startTime"+(t+1)),BeanUtil.getProperty(bean, "endTime"+(t+1)) ))
                .collect(Collectors.toList());

        Calendar instance = Calendar.getInstance(TimeZone.getTimeZone(ZoneId.of("Asia/Shanghai")));
        instance.setTime(date);
        int i = instance.get(Calendar.DAY_OF_WEEK);
        i = (i==1? 6 : i-2);
        return weekTimeDTOS.get(i);
    }

}
